#include <sstream>
#include <stddef.h> //offsetof
#include <ifaddrs.h>
#include <netdb.h>
#include "address.h"
#include "endian.h"
#include "log.h"


namespace framework
{

static framework::Logger::ptr g_logger = FRAMEWORK_LOG_NAME("system");

template<class T>
static T CreateMask(uint32_t bits)
{
    //假设IPv4子网掩码为24位 255.255.255.0
    //2 ^ (32 - 24) = 2 ^ 8 = 256 , 地址为0~255 , 256 - 1 ,所以广播地址为x.x.x.255 
    return (1 << (sizeof(T) * 8 - bits)) - 1;
}

//求出value的二进制位有多少个1
template<class T>
static uint32_t CountBytes(T value)
{
    uint32_t result = 0;
    for(; value; ++result)
    {
        value &= value - 1;
    }
    return result;
}

//==================================== Address ====================================

//通过sockaddr创建Address
Address::ptr Address::Create(const sockaddr* addr, socklen_t addrlen)
{
    if(addr == nullptr)
    {
        return nullptr;
    }

    Address::ptr result;
    switch (addr->sa_family)
    {
    case AF_INET:
        {
            result.reset(new IPv4Address(*(const sockaddr_in*)addr));
        }
        break;
    case AF_INET6:
        {
            result.reset(new IPv6Address(*(const sockaddr_in6*)addr));
        }
        break;
    default:
        result.reset(new UnknownAddress(*addr));
        break;
    }

    return result;
}


/*
getaddrinfo 可以确保网络应用程序在不同平台和网络环境中都能够正确地解析主机名和服务名，并且能够以一致的方式处理网络地址。
这使得网络应用程序具有良好的可移植性和灵活性。
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);

getaddrinfo 函数是在 Linux 和其他类 Unix 系统中用于获取主机名（hostname）和服务名（service name）的地址信息的函数。
这个函数用于将主机名和服务名解析为一个或多个套接字地址结构体，以便用于网络通信。
1.node：这是一个指向主机名或 IP 地址的 C 字符串的指针。它用于指定要解析的主机名或 IP 地址。可以传递主机名（如 "www.example.com"）或者
IP 地址（如 "192.168.1.1"）。如果传递主机名，getaddrinfo 会尝试将主机名解析为一个或多个 IP 地址。
2.service：这是一个指向服务名或端口号的 C 字符串的指针。它用于指定要解析的服务名或端口号。服务名通常是一个协议（如 "http" 或 "ftp"）的别名，
也可以是端口号的字符串表示形式（如 "80"）。getaddrinfo 会将服务名解析为一个或多个端口号。
3.hints：这是一个指向 addrinfo 结构体的指针，用于提供一些关于地址解析的提示。可以使用 hints 参数来指定期望的地址族（IPv4、IPv6 或其他）、
套接字类型（如 SOCK_STREAM 或 SOCK_DGRAM）、标志等。如果不需要特定的提示，可以将 hints 设置为 nullptr。
4.res：这是一个指向 addrinfo 结构体的指针的指针，用于接收解析后的地址信息。getaddrinfo 函数会分配一个链表，其中包含一个或多个 addrinfo 结构体，
每个结构体描述了一个可用的地址。您需要在使用完地址信息后，调用 freeaddrinfo 来释放内存。
5.getaddrinfo 函数的作用是根据主机名和服务名获取一个或多个套接字地址结构体。这些地址结构体包含了网络通信所需的信息，包括 IP 地址、端口号、
地址族等。通常，程序员会使用 getaddrinfo 来获取要用于网络通信的套接字地址信息，然后将这些信息传递给 socket 函数来创建套接字，或者传递给 
connect、bind、listen 等函数来设置套接字参数和执行网络通信操作。
*/
//通过host地址返回对应条件的所有Address
bool Address::Lookup(std::vector<Address::ptr>& result, const std::string& host,
    int family, int type, int protocol)
{
    addrinfo hints, *results, *next;
    hints.ai_flags = 0;           //用于控制地址查找行为的标志
    hints.ai_family = family;     //地址族，如 AF_INET（IPv4） 或 AF_INET6（IPv6）
    hints.ai_socktype = type;     //套接字类型，如 SOCK_STREAM（流套接字） 或 SOCK_DGRAM（数据报套接字）,设置为SOCK_STREAM将限制每个地址最多一个addrinfo
    hints.ai_protocol = protocol; //传输协议，如 IPPROTO_TCP（TCP） 或 IPPROTO_UDP（UDP）
    hints.ai_addrlen = 0;         //套接字地址长度
    hints.ai_canonname = NULL;    //主机名的规范名
    hints.ai_addr = NULL;         //套接字地址的指针
    hints.ai_next = NULL;         //指向下一个 addrinfo 结构体的指针

    //将第一个':'之前的字符串赋给node 如何没有':'则node = host
    std::string node;

    // 在 IPv6 地址中，如果地址的最后一部分包含一个冒号（:），然后跟随一个端口号（通常是一个
    // 十进制数字），则这个端口号被认为是一个 "service"。这通常用于标识网络服务或应用程序正
    // 在使用的端口号。IPv6 地址的这种形式通常用于 URL 地址中，以指定网络资源的地址和端口号。
    // 例：[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80
    const char* service = NULL; //service指向端口号的第一个字符

    //检查是否为 IPv6的地址
    if(!host.empty() && host[0] == '[')
    {
        //查找']'的位置
        const char* endIpv6 = (const char*)memchr(host.c_str() + 1, ']', host.size() - 1);
        if(endIpv6) //如果找到了
        {
            //这里应该检查一下是否越界
            //if(*(endIpv6 + 1) != '\0' && *(endIpv6 + 1) == ':')
            if(*(endIpv6 + 1) == ':')
            {
                service = endIpv6 + 2;
            }
            //取出[ 和 ] 中间的字符串
            node = host.substr(1, endIpv6 - host.c_str() - 1);
        }
    }

    //如果node为空，则为IPv4的地址
    if(node.empty())
    {
        service = (const char*)memchr(host.c_str(), ':', host.size());
        if(service)
        {
            //从service开始找，找到host结尾-1的位置
            if(!memchr(service + 1, ':', host.c_str() + host.size() - service - 1))
            {
                //将第一个':'之前的字符串赋给node
                node = host.substr(0, service - host.c_str());
                ++service; //service指向端口号的第一个字符
            }
        }
    }

    if(node.empty())
    {
        node = host;
    }

    // std::cout << node << std::endl;
    // std::cout << service << std::endl;

    //获取addr
    int error = getaddrinfo(node.c_str(), service, &hints, &results);
    if(error)
    {
        FRAMEWORK_LOG_DEBUG(g_logger) << "Address::Lookup getaddress(" << host << ", "
            << family << ", " << type << ") errno=" << errno
            << " errstr=" << gai_strerror(errno);
        return false;
    }

    next = results;
    while(next)
    {
        // result.emplace_back(Create(next->ai_addr, (socklen_t)next->ai_addrlen, uint16_t(std::stoi(service))));
        result.emplace_back(Create(next->ai_addr, (socklen_t)next->ai_addrlen));
        next = next->ai_next;
    }

    freeaddrinfo(results);
    return !result.empty();
}

//通过host地址返回对应条件的任意Address
Address::ptr Address::LookupAny(const std::string& host,
    int family, int type, int protocol)
{
    std::vector<Address::ptr> result;
    if(Lookup(result, host, family, type, protocol))
    {
        return result[0];
    }
    return nullptr;
}

//通过host地址返回对应条件的任意Address
std::shared_ptr<IPAddress> Address::LookupAnyIPAddress(const std::string& host,
    int family, int type, int protocol)
{
    std::vector<Address::ptr> result;
    if(Lookup(result, host, family, type, protocol))
    {
        for(auto& t: result)
        {
            IPAddress::ptr v = std::dynamic_pointer_cast<IPAddress>(t);
            if(v)
            {
                return v;
            }
        }
    }
    return nullptr;
}


//brief  返回本机所有网卡的<网卡名, 地址, 子网掩码位数>
bool Address::GetInterfaceAddresses(std::multimap<std::string, 
    std::pair<Address::ptr, uint32_t>>& result, int family)
{
    struct ifaddrs *next, *results;
    if(getifaddrs(&results) != 0)
    {
        FRAMEWORK_LOG_DEBUG(g_logger) << "Address::GetInterfaceAddresses getifaddrs "
            " err=" << errno << " errstr=" << strerror(errno);
        return false;
    }

    try
    {
        for(next = results; next; next = next->ifa_next)
        {
            Address::ptr addr;
            uint32_t prefix_len = 0u;
            //AF_UNSPEC表示可以是任何协议族
            if(family != AF_UNSPEC && family != next->ifa_addr->sa_family)
            {
                continue;
            }

            switch (next->ifa_addr->sa_family)
            {
            case AF_INET:
                {
                    addr = Create(next->ifa_addr, sizeof(sockaddr_in));
                    //获取网卡的子网掩码
                    uint32_t netMask = ((sockaddr_in*)next->ifa_netmask)->sin_addr.s_addr;
                    prefix_len = CountBytes(netMask);
                }
                break;
            case AF_INET6:
                {
                    addr = Create(next->ifa_addr, sizeof(sockaddr_in6));
                    in6_addr& netMask = ((sockaddr_in6*)next->ifa_netmask)->sin6_addr;
                    for(int i = 0; i < 16; ++i)
                    {
                        prefix_len += CountBytes(netMask.s6_addr[i]);
                    }
                }
                break;
            default:
                break;
            }

            if(addr)
            {
                result.insert(std::make_pair(next->ifa_name, 
                            std::make_pair(addr, prefix_len)));
            }
        }
        
    }
    catch(...)
    {
        FRAMEWORK_LOG_ERROR(g_logger) << "Address::GetInterfaceAddresses exception";
        freeifaddrs(results);
        return false;
    }
    
    freeifaddrs(results);
    return !result.empty();
}

//brief  获取指定网卡的地址和子网掩码位数
bool Address::GetInterfaceAddresses(std::vector<std::pair<Address::ptr, uint32_t> >&result
    ,const std::string& iface, int family)
{
    if(iface.empty() || iface == "*")
    {
        if(family == AF_INET || family == AF_UNSPEC)
        {
            result.push_back(std::make_pair(Address::ptr(new IPv4Address()), 0u));
        }
        if(family == AF_INET6 || family == AF_UNSPEC)
        {
            result.push_back(std::make_pair(Address::ptr(new IPv6Address()), 0u));
        }
        return true;
    }

    std::multimap<std::string, std::pair<Address::ptr, uint32_t>> tempMap;
    if(!GetInterfaceAddresses(tempMap, family))
    {
        return false;
    }

    auto its = tempMap.equal_range(iface);
    for(; its.first != its.second; ++its.first)
    {
        result.push_back(its.first->second);
    }
    return !result.empty();
}

//返回协议族
int Address::getFamily() const
{
    return getAddr()->sa_family;
}

//返回字符串类型地址
std::string Address::toString() const
{
    std::stringstream ss;
    insert(ss);
    return ss.str();
}

bool Address::operator<(const Address& rhs) const
{
    socklen_t minlen = std::min(getAddrLen(), rhs.getAddrLen());
    int result = memcmp(getAddr(), rhs.getAddr(), minlen);
    if(result < 0)  //str1 < str2
    {
        return true;
    }
    else if(result > 0) //str1 > str2
    {
        return false;
    }
    else if(getAddrLen() < rhs.getAddrLen())
    {
        return true;
    }
    return false;
}
bool Address::operator==(const Address& rhs) const
{
    return getAddrLen() == rhs.getAddrLen()
        && 0 == memcmp(getAddr(), rhs.getAddr(), getAddrLen());
}
bool Address::operator!=(const Address& rhs) const
{
    return !(*this == rhs);
}

//==================================== Address ====================================



//================================== IPAddress ==================================

//通过域名,IP,服务器名创建IPAddress
IPAddress::ptr IPAddress::Create(const char* address, uint16_t port)
{
    addrinfo hints, *results;
    memset(&hints, 0, sizeof(addrinfo));

    //这个标志会禁止任何可能耗时的网络主机地址查找。
    // hints.ai_flags = AI_NUMERICHOST;
    //这个常量表示调用者接受任何协议族。可以用来返回主机名对应的 IPv4 和 IPv6 地址。
    hints.ai_family = AF_UNSPEC;     

    int res = getaddrinfo(address, NULL, &hints, &results);
    if(res)
    {
        FRAMEWORK_LOG_DEBUG(g_logger) << "IPAddress::Create(" << address << ", "
            << port << ") rt=" << res << " errno=" << errno
            << " errstr=" << strerror(errno);
        return nullptr;
    }

    //std::dynamic_pointer_cast 是 C++11 中的一个模板函数，用于将一个 std::shared_ptr 类型
    //的指针转换为另一个类型的 std::shared_ptr 指针。它与 dynamic_cast 的用法类似，当指针是
    //智能指针时候，向下转换，用 dynamic_cast 则编译不能通过，此时需要使用 dynamic_pointer_cast。
    try
    {
        IPAddress::ptr resul = std::dynamic_pointer_cast<IPAddress>(
                Address::Create(results->ai_addr, (socklen_t)results->ai_addrlen));
        freeaddrinfo(results);
        return resul;
    }
    catch(...)
    {
        freeaddrinfo(results);
        return nullptr;
    }
    
}

//================================== IPAddress ==================================



//================================ IPv4Address ================================

//使用点分十进制地址创建IPv4Address
IPv4Address::ptr IPv4Address::Create(const char* address, uint16_t port)
{
    IPv4Address::ptr rt(new IPv4Address);
    rt->m_addr.sin_port = byteswapOnLittleEndian(port);
    int res = inet_pton(AF_INET, address, &rt->m_addr.sin_addr);
    if(res <= 0)
    {
        FRAMEWORK_LOG_DEBUG(g_logger) << "IPv4Address::Create(" << address << ", "
            << port << ") rt=" << res << " errno=" << errno
            << " errstr=" << strerror(errno);
        return nullptr;
    }
    return rt;
}

//通过sockaddr_in构造IPv4Address
IPv4Address::IPv4Address(const sockaddr_in& address)
{
    this->m_addr = address;
    // m_addr.sin_port = framework::byteswapOnLittleEndian(port);
}

//通过二进制地址构造IPv4Address
IPv4Address::IPv4Address(uint32_t address, uint16_t port)
{
    memset(&this->m_addr, 0, sizeof(sockaddr_in));
    m_addr.sin_family = AF_INET;
    m_addr.sin_port = framework::byteswapOnLittleEndian(port);
    m_addr.sin_addr.s_addr = framework::byteswapOnLittleEndian(address);  //小端转大端
}

//返回sockaddr指针,只读
const sockaddr* IPv4Address::getAddr() const
{
    return (sockaddr*)&m_addr;
}

//返回sockaddr指针,读写
sockaddr* IPv4Address::getAddr()
{
    return (sockaddr*)&m_addr;
}

//返回sockaddr的长度
socklen_t IPv4Address::getAddrLen() const
{
    return sizeof(m_addr);
}

//可读性输出地址
std::ostream& IPv4Address::insert(std::ostream& os) const
{
    //同 inet_ntoa 的功能
    uint32_t addr = framework::byteswapOnLittleEndian(this->m_addr.sin_addr.s_addr); //大端转小端
    os << ((addr >> 24) & 0xff) << "."
       << ((addr >> 16) & 0xff) << "."
       << ((addr >> 8) & 0xff) << "."
       << (addr & 0xff);
    os << ":" << framework::byteswapOnLittleEndian(this->m_addr.sin_port);
    return os;
}

//获取该地址的广播地址
IPAddress::ptr IPv4Address::broadcastAddress(uint32_t prefix_len)
{
    //如果子网掩码位数大于32
    if(prefix_len > 32)
    {
        return nullptr;
    }

    sockaddr_in baddr(m_addr);
    //prefix_len = 24; 192.168.1.42 | 255 = 192.168.1.255
    baddr.sin_addr.s_addr |= byteswapOnLittleEndian(CreateMask<uint32_t>(prefix_len)); //小端转大端

    return IPv4Address::ptr(new IPv4Address(baddr));
}

//获取该地址的网段
IPAddress::ptr IPv4Address::networdAddress(uint32_t prefix_len)
{
    //如果子网掩码位数大于32
    if(prefix_len > 32)
    {
        return nullptr;
    }
    sockaddr_in baddr(m_addr);
    //prefix_len = 24; 192.168.1.42 & 255.255.255.0 = 192.168.1.0
    baddr.sin_addr.s_addr &= (~byteswapOnLittleEndian(CreateMask<uint32_t>(prefix_len)));

    return IPv4Address::ptr(new IPv4Address(baddr));

}

//获取子网掩码地址
IPAddress::ptr IPv4Address::subnetMask(uint32_t prefix_len)
{
    sockaddr_in subnet;
    memset(&subnet, 0, sizeof(subnet));
    subnet.sin_family = AF_INET;
    subnet.sin_addr.s_addr = ~byteswapOnLittleEndian(CreateMask<uint32_t>(prefix_len));
    return IPv4Address::ptr(new IPv4Address(subnet));
}

//返回端口号
uint32_t IPv4Address::getPort() const
{
    return byteswapOnLittleEndian(m_addr.sin_port);
}

//设置端口号
void IPv4Address::setPort(uint16_t v)
{
    m_addr.sin_port = byteswapOnLittleEndian(v);
}
//================================ IPv4Address ================================



//================================ IPv6Address ================================
//通过IPv6地址字符串构造IPv6Address
IPv6Address::ptr IPv6Address::Create(const char* address, uint16_t port)
{
    IPv6Address::ptr rt(new IPv6Address);
    rt->m_addr.sin6_port = byteswapOnLittleEndian(port);
    int result = inet_pton(AF_INET6, address, &rt->m_addr.sin6_addr);
    if(result <= 0)
    {
        FRAMEWORK_LOG_DEBUG(g_logger) << "IPv6Address::Create(" << address << ", "
            << port << ") rt=" << result << " errno=" << errno
            << " errstr=" << strerror(errno);
        return nullptr;
    }

    return rt;
}

//无参构造
IPv6Address::IPv6Address()
{
    memset(&m_addr, 0, sizeof(m_addr));
    m_addr.sin6_family = AF_INET6;
}

//通过sockaddr_in构造IPv6Address
//address sockaddr_in6结构体
IPv6Address::IPv6Address(const sockaddr_in6& address)
{
    m_addr = address;
    // m_addr.sin6_port = byteswapOnLittleEndian(port);
}

//通过IPv6二进制地址构造IPv6Address
IPv6Address::IPv6Address(const uint8_t address[16], uint16_t port)
{
    memset(&m_addr, 0, sizeof(m_addr));
    m_addr.sin6_family = AF_INET6;
    m_addr.sin6_port = byteswapOnLittleEndian(port);
    memcpy(&m_addr.sin6_addr.s6_addr, address, 16); //?是否需要转大端
}


//返回sockaddr指针,只读
const sockaddr* IPv6Address::getAddr() const
{
    return (sockaddr*)&m_addr;
}
//返回sockaddr指针,读写
sockaddr* IPv6Address::getAddr()
{
    return (sockaddr*)&m_addr;
}
//返回sockaddr的长度
socklen_t IPv6Address::getAddrLen() const
{
    return sizeof(m_addr);
}

//可读性输出地址
std::ostream& IPv6Address::insert(std::ostream& os) const
{
    //"2001:0da8:0207:0000:0000:0000:0000:8207"
    os << "[";
    uint16_t* addr = (uint16_t*)m_addr.sin6_addr.s6_addr;
    bool used_zeros = false;
    //将IPv6地址分为8份
    for(size_t i = 0; i < 8; ++i) {
        if(addr[i] == 0 && !used_zeros) 
        {
            continue;
        }
        if(i && addr[i - 1] == 0 && !used_zeros) //第一次出现0 或者 第一次出现多个连续0时用::代替
        { 
            os << ":";
            used_zeros = true;
        }
        if(i) 
        {
            os << ":";
        }
        os << std::hex << (int)byteswapOnLittleEndian(addr[i]) << std::dec;//16进制输出
    }

    if(!used_zeros && addr[7] == 0) //如果第一次出现0并且一直到最后都是0
    { 
        os << "::";
    }

    os << "]:" << byteswapOnLittleEndian(m_addr.sin6_port);
    return os;
}
//获取该地址的广播地址
IPAddress::ptr IPv6Address::broadcastAddress(uint32_t prefix_len)
{
    sockaddr_in6 baddr(m_addr);
    //uint8_t s6_addr[16];
    baddr.sin6_addr.s6_addr[prefix_len / 8] |=
        CreateMask<uint8_t>(prefix_len % 8);
    for(int i = prefix_len / 8 + 1; i < 16; ++i) {
        baddr.sin6_addr.s6_addr[i] = 0xff;
    }
    return IPv6Address::ptr(new IPv6Address(baddr));
}
//获取该地址的网段
IPAddress::ptr IPv6Address::networdAddress(uint32_t prefix_len)
{
    sockaddr_in6 baddr(m_addr);
    baddr.sin6_addr.s6_addr[prefix_len / 8] &=
        CreateMask<uint8_t>(prefix_len % 8);
    for(int i = prefix_len / 8 + 1; i < 16; ++i) {
        baddr.sin6_addr.s6_addr[i] = 0x00;
    }
    return IPv6Address::ptr(new IPv6Address(baddr));
}
//获取子网掩码地址
IPAddress::ptr IPv6Address::subnetMask(uint32_t prefix_len)
{
    sockaddr_in6 subnet;
    memset(&subnet, 0, sizeof(subnet));
    subnet.sin6_family = AF_INET6;
    subnet.sin6_addr.s6_addr[prefix_len /8] =
        ~CreateMask<uint8_t>(prefix_len % 8);

    for(uint32_t i = 0; i < prefix_len / 8; ++i) {
        subnet.sin6_addr.s6_addr[i] = 0xff;
    }
    return IPv6Address::ptr(new IPv6Address(subnet));
}
//返回端口号
uint32_t IPv6Address::getPort() const
{
    return byteswapOnLittleEndian(m_addr.sin6_port);
}
//设置端口号
void IPv6Address::setPort(uint16_t v)
{
    m_addr.sin6_port = byteswapOnLittleEndian(v);
}

//================================ IPv6Address ================================




//================================ UnixAddress ================================

//计算sockaddr_un.sun_path的最大长度，空余一个'\0'的大小
static const size_t MAX_PATH_LEN = sizeof(((sockaddr_un*)0)->sun_path) - 1;

UnixAddress::UnixAddress()
{
    memset(&m_addr, 0, sizeof(m_addr));
    m_addr.sun_family = AF_UNIX;
    m_length = offsetof(sockaddr_un, sun_path) + MAX_PATH_LEN;
}

//通过路径构造UnixAddress
UnixAddress::UnixAddress(const std::string& path)
{
    memset(&m_addr, 0, sizeof(m_addr));
    m_addr.sun_family = AF_UNIX;
    m_length = path.size() + 1;

    if(!path.empty() && path[0] == '\0')
    {
        --m_length;
    }

    if(m_length > sizeof(m_addr.sun_path))
    {
        throw std::logic_error("path too long");
    }

    memcpy(m_addr.sun_path, path.c_str(), m_length);
                //计算sun_path变量在sockaddr_un结构体的偏移量
    m_length += offsetof(sockaddr_un, sun_path);
}

void UnixAddress::setAddrLen(uint32_t v)
{
    m_length = v;
}
std::string UnixAddress::getPath() const
{
    std::stringstream ss;
    //如果m_addr.sun_path为空
    if(m_length > offsetof(sockaddr_un, sun_path)
        && m_addr.sun_path[0] == '\0')
    {
        ss << "\\0" << std::string(m_addr.sun_path + 1,
            m_length - offsetof(sockaddr_un, sun_path) - 1);
    }
    else
    {
        ss << m_addr.sun_path;
    }
    return ss.str();
}

//返回sockaddr指针,只读
const sockaddr* UnixAddress::getAddr() const
{
    return (sockaddr*)&m_addr;
}
//返回sockaddr指针,读写
sockaddr* UnixAddress::getAddr()
{
    return (sockaddr*)&m_addr;
}
//返回sockaddr的长度
socklen_t UnixAddress::getAddrLen() const
{
    return m_length;
}
//可读性输出地址
std::ostream& UnixAddress::insert(std::ostream& os) const
{
    if(m_length > offsetof(sockaddr_un, sun_path)
            && m_addr.sun_path[0] == '\0') 
    {
        return os << "\\0" << std::string(m_addr.sun_path + 1,
                m_length - offsetof(sockaddr_un, sun_path) - 1);
    }
    return os << m_addr.sun_path;
}
//================================ UnixAddress ================================



//================================ UnknownAddress ================================
UnknownAddress::UnknownAddress(int family)
{
    memset(&m_addr, 0, sizeof(sockaddr));
    m_addr.sa_family = family;
}
UnknownAddress::UnknownAddress(const sockaddr& addr)
{
    m_addr = addr;
}

//返回sockaddr指针,只读
const sockaddr* UnknownAddress::getAddr() const
{
    return &m_addr;
}
//返回sockaddr指针,读写
sockaddr* UnknownAddress::getAddr()
{
    return &m_addr;
}
//返回sockaddr的长度
socklen_t UnknownAddress::getAddrLen() const
{
    return sizeof(m_addr);
}
//可读性输出地址
std::ostream& UnknownAddress::insert(std::ostream& os) const
{
    os << "[UnknownAddress family=" << m_addr.sa_family << "]";
    return os;
}
//================================ UnknownAddress ================================

//流式输出Address
std::ostream& operator<<(std::ostream& os, const Address& addr)
{
    return addr.insert(os);
}


} // namespace framework

